** This file contains commands to replicate the analysis in Jonathan Golub and Michal Ovádek (2024) "Informal Procedures, 
** Institutional Change, and EU Decision-Making: Evaluating the Effects of the 1974 Paris Summit," Journal of European Public
** Policy https://doi.org/10.1080/13501763.2024.2434071


*Our replication datasets fix errors discovered in version 1.0 of EUPROPS (Golub 2024):

*COM(1973)0041 was adopted 23jan1973 as 31973R0181
*COM(1973)0142-04 legal basis is 11957E238;11972B108
*COM(1973)0455 legal basis is 11957E113;21972A0722(05)-N6A2P2
*COM(1973)0659-02/05 legal basis for each is 11957E235;31971G0055
*COM(1973)1726-01/02 legal basis for each is 11957E113
*COM(1974)0860-01 legal basis is 11965F024
*COM(1975)0247 legal basis is 11957A050 
*COM(1975)0339 legal basis is 11957E100
*COM(1975)0515 legal basis is 11957E043
*COM(1975)0521 legal basis is 11957E043
*COM(1975)0545 was adopted 21oct1976 as 31976R2615
*COM(1975)0558-01/03 legal basis for each is 11957E100
*COM(1975)0608 legal basis is 11972B/ACT-ANNEX7CHAPTER6P3cL2
*COM(1976)0164 legal basis is 11957E043
*COM(1976)0514 legal basis is 11957E100

use "C:\Paris replication data_short.dta", clear

*Alter date of adoption to set duration=1 for cases that were adopted before they were proposed (i.e. duration<=0)

replace adopted=td(17sep1976) if EUPROPID==("COM(1976)0492")
replace adopted=td(21sep1976) if EUPROPID==("COM(1976)0498")
replace adopted=td(18feb1976) if EUPROPID==("COM(1976)0061")
replace adopted=td(28mar1973) if EUPROPID==("COM(1973)0491")

*Generate variables for time period (pre-Paris/post-Paris), voting rule, EP consultation
 
gen proposedpre=1 if proposed<=td(10dec1974)
replace proposedpre=0 if proposed>td(10dec1974)
gen proposedpost=0 if proposed<=td(10dec1974)
replace proposedpost=1 if proposed>td(10dec1974)
gen TVCcase=1 if proposedpre==1 & adopted>td(10dec1974)
label variable type "type"
label define type 1 "pdir" 2 "preg" 3 "pdec"
encode type, gen(type_cat) label(type)
label define rule 1 "vote" 2 "unanimity" 3 "ambiguous"
encode rule26mar2024, gen(rule_cat) label(rule) 
gen qmv=1 if rule26mar2024=="vote"
replace qmv=0 if rule26mar2024=="unanimity"
gen qmvpost=qmv*proposedpost
gen consult=1 if ep26mar2024=="consult"
replace consult=0 if ep26mar2024=="none"
sort proposedpre rule26mar2024

*Count proposals of each type and total by period

by proposedpre, sort: egen periodpdirs = total(type=="pdir")
by proposedpre, sort: egen periodpregs = total(type=="preg")
by proposedpre, sort: egen periodpdecs = total(type=="pdec")
by proposedpre, sort: egen periodproposals = total(type=="pdir" | type=="preg" | type=="pdec")

gen totalpropsbytypepre=.
replace totalpropsbytypepre=periodpdirs if type=="pdir" & proposedpre==1
replace totalpropsbytypepre=periodpregs if type=="preg" & proposedpre==1
replace totalpropsbytypepre=periodpdecs if type=="pdec" & proposedpre==1

gen totalpropsbytypepost=.
replace totalpropsbytypepost=periodpdirs if type=="pdir" & proposedpre==0
replace totalpropsbytypepost=periodpregs if type=="preg" & proposedpre==0
replace totalpropsbytypepost=periodpdecs if type=="pdec" & proposedpre==0

*Count proposals of each voting rule by period

by proposedpre, sort: egen periodqmv = total(rule26mar2024=="vote")
by proposedpre, sort: egen periodunan = total(rule26mar2024=="unanimity")
by proposedpre, sort: egen periodambig = total(rule26mar2024=="ambiguous")

gen totalpropsbyrulepre=.
replace totalpropsbyrulepre=periodqmv if rule26mar2024=="vote" & proposedpre==1
replace totalpropsbyrulepre=periodunan if rule26mar2024=="unanimity" & proposedpre==1
replace totalpropsbyrulepre=periodambig if rule26mar2024=="ambiguous" & proposedpre==1

gen totalpropsbyrulepost=.
replace totalpropsbyrulepost=periodqmv if rule26mar2024=="vote" & proposedpre==0
replace totalpropsbyrulepost=periodunan if rule26mar2024=="unanimity" & proposedpre==0
replace totalpropsbyrulepost=periodambig if rule26mar2024=="ambiguous" & proposedpre==0

*Calculate proportion of proposals subject to each voting rule, by type and period

by proposedpre, sort: egen periodqmvpdirs = total(type=="pdir") if rule26mar2024=="vote"
by proposedpre, sort: egen periodqmvpregs = total(type=="preg") if rule26mar2024=="vote"
by proposedpre, sort: egen periodqmvpdecs = total(type=="pdec") if rule26mar2024=="vote"
by proposedpre, sort: egen periodunanpdirs = total(type=="pdir") if rule26mar2024=="unanimity"
by proposedpre, sort: egen periodunanpregs = total(type=="preg") if rule26mar2024=="unanimity"
by proposedpre, sort: egen periodunanpdecs = total(type=="pdec") if rule26mar2024=="unanimity"
by proposedpre, sort: egen periodambigpdirs = total(type=="pdir") if rule26mar2024=="ambiguous"
by proposedpre, sort: egen periodambigpregs = total(type=="preg") if rule26mar2024=="ambiguous"
by proposedpre, sort: egen periodambigpdecs = total(type=="pdec") if rule26mar2024=="ambiguous"

gen pctqmvpdirspre=round(periodqmvpdirs/periodpdirs*100, 0.01) if type=="pdir" & proposedpre==1
gen pctqmvpregspre=round(periodqmvpregs/periodpregs*100, 0.01) if type=="preg" & proposedpre==1
gen pctqmvpdecspre=round(periodqmvpdecs/periodpdecs*100, 0.01) if type=="pdec" & proposedpre==1
gen pctqmvpdirspost=round(periodqmvpdirs/periodpdirs*100, 0.01) if type=="pdir" & proposedpre==0
gen pctqmvpregspost=round(periodqmvpregs/periodpregs*100, 0.01) if type=="preg" & proposedpre==0
gen pctqmvpdecspost=round(periodqmvpdecs/periodpdecs*100, 0.01) if type=="pdec" & proposedpre==0

gen pctunanpdirspre=round(periodunanpdirs/periodpdirs*100, 0.01) if type=="pdir" & proposedpre==1
gen pctunanpregspre=round(periodunanpregs/periodpregs*100, 0.01) if type=="preg" & proposedpre==1
gen pctunanpdecspre=round(periodunanpdecs/periodpdecs*100, 0.01) if type=="pdec" & proposedpre==1
gen pctunanpdirspost=round(periodunanpdirs/periodpdirs*100, 0.01) if type=="pdir" & proposedpre==0
gen pctunanpregspost=round(periodunanpregs/periodpregs*100, 0.01) if type=="preg" & proposedpre==0
gen pctunanpdecspost=round(periodunanpdecs/periodpdecs*100, 0.01) if type=="pdec" & proposedpre==0

gen pctambigpdirspre=round(periodambigpdirs/periodpdirs*100, 0.01) if type=="pdir" & proposedpre==1
gen pctambigpregspre=round(periodambigpregs/periodpregs*100, 0.01) if type=="preg" & proposedpre==1
gen pctambigpdecspre=round(periodambigpdecs/periodpdecs*100, 0.01) if type=="pdec" & proposedpre==1
gen pctambigpdirspost=round(periodambigpdirs/periodpdirs*100, 0.01) if type=="pdir" & proposedpre==0
gen pctambigpregspost=round(periodambigpregs/periodpregs*100, 0.01) if type=="preg" & proposedpre==0
gen pctambigpdecspost=round(periodambigpdecs/periodpdecs*100, 0.01) if type=="pdec" & proposedpre==0

gen pctpropsbyrulepre=.
replace pctpropsbyrulepre = pctqmvpdirspre if type=="pdir" & rule26mar2024=="vote" & proposedpre==1
replace pctpropsbyrulepre = pctqmvpregspre if type=="preg" & rule26mar2024=="vote" & proposedpre==1
replace pctpropsbyrulepre = pctqmvpdecspre if type=="pdec" & rule26mar2024=="vote" & proposedpre==1
replace pctpropsbyrulepre = pctunanpdirspre if type=="pdir" & rule26mar2024=="unanimity" & proposedpre==1
replace pctpropsbyrulepre = pctunanpregspre if type=="preg" & rule26mar2024=="unanimity" & proposedpre==1
replace pctpropsbyrulepre = pctunanpdecspre if type=="pdec" & rule26mar2024=="unanimity" & proposedpre==1
replace pctpropsbyrulepre = pctambigpdirspre if type=="pdir" & rule26mar2024=="ambiguous" & proposedpre==1
replace pctpropsbyrulepre = pctambigpregspre if type=="preg" & rule26mar2024=="ambiguous" & proposedpre==1
replace pctpropsbyrulepre = pctambigpdecspre if type=="pdec" & rule26mar2024=="ambiguous" & proposedpre==1

gen pctpropsbyrulepost=.
replace pctpropsbyrulepost = pctqmvpdirspost if type=="pdir" & rule26mar2024=="vote" & proposedpre==0
replace pctpropsbyrulepost = pctqmvpregspost if type=="preg" & rule26mar2024=="vote" & proposedpre==0
replace pctpropsbyrulepost = pctqmvpdecspost if type=="pdec" & rule26mar2024=="vote" & proposedpre==0
replace pctpropsbyrulepost = pctunanpdirspost if type=="pdir" & rule26mar2024=="unanimity" & proposedpre==0
replace pctpropsbyrulepost = pctunanpregspost if type=="preg" & rule26mar2024=="unanimity" & proposedpre==0
replace pctpropsbyrulepost = pctunanpdecspost if type=="pdec" & rule26mar2024=="unanimity" & proposedpre==0
replace pctpropsbyrulepost = pctambigpdirspost if type=="pdir" & rule26mar2024=="ambiguous" & proposedpre==0
replace pctpropsbyrulepost = pctambigpregspost if type=="preg" & rule26mar2024=="ambiguous" & proposedpre==0
replace pctpropsbyrulepost = pctambigpdecspost if type=="pdec" & rule26mar2024=="ambiguous" & proposedpre==0

*Figure 2

graph bar totalpropsbytypepre, over(type_cat) ytitle("n", orientation(horizontal)) title("PRE" " ") blabel(bar, format(%9.0f)) name(proposalsbytypepre, replace)
graph bar totalpropsbytypepost, over(type_cat) ytitle("n", orientation(horizontal)) title("POST" " ") blabel(bar, format(%9.0f)) name(proposalsbytypepost, replace)

graph combine proposalsbytypepre proposalsbytypepost, ycommon title("Number of proposals by type, pre- v. post-communiqué", pos(6))

*Figure 3

graph bar totalpropsbyrulepre, over(rule_cat) ytitle("n", orientation(horizontal)) title("PRE" " ") blabel(bar, format(%9.0f)) name(proposalsbyrulepre, replace)
graph bar totalpropsbyrulepost, over(rule_cat) ytitle("n", orientation(horizontal)) title("POST" " ") blabel(bar, format(%9.0f)) name(proposalsbyrulepost, replace)

graph combine proposalsbyrulepre proposalsbyrulepost, ycommon title("Number of proposals by voting rule, pre- v. post-communiqué", pos(6))

*Figure 4

graph bar pctpropsbyrulepre if rule26mar2024=="vote", over(type) ytitle("%", orientation(horizontal)) title("PRE" " ") blabel(bar, format(%9.1f)) name(pctproposalsQMVprebytype, replace)
graph bar pctpropsbyrulepost if rule26mar2024=="vote", over(type) ytitle("%", orientation(horizontal)) title("POST" " ") blabel(bar, format(%9.1f)) name(pctproposalsQMVpostbytype, replace)

graph combine pctproposalsQMVprebytype pctproposalsQMVpostbytype, ycommon title("Percentage of proposals subject to QMV by type, pre- v. post-communiqué", pos(6))

*Figure 5

graph bar pctpropsbyrulepre if rule26mar2024=="unanimity", over(type) ytitle("%", orientation(horizontal)) title("PRE" " ") blabel(bar, format(%9.1f)) name(pctproposalsunanprebytype, replace)
graph bar pctpropsbyrulepost if rule26mar2024=="unanimity", over(type) ytitle("%", orientation(horizontal)) title("POST" " ") blabel(bar, format(%9.1f)) name(pctproposalsunanpostbytype, replace)

graph combine pctproposalsunanprebytype pctproposalsunanpostbytype, ycommon title("Percentage of proposals subject to unanimity by type, pre- v. post-communiqué", pos(6) span size(m))

*Medium-n analysis
 
gen mediumn=1 if EUPROPID=="COM(1973)0491" | EUPROPID=="COUNCIL(R/1423/74)" | EUPROPID=="COM(1976)0014" | EUPROPID=="COM(1976)0114" | EUPROPID=="COUNCIL(R/1908/1/76)" | EUPROPID=="COM(1976)0485" | EUPROPID=="COM(1976)0636" | EUPROPID=="COM(1973)0213-02" | EUPROPID=="COM(1973)0213-01" | EUPROPID=="COM(1973)0761" | EUPROPID=="COM(1973)1257" | EUPROPID=="COM(1973)1396" | EUPROPID=="COM(1973)1632" | EUPROPID=="COM(1973)1856" | EUPROPID=="COM(1974)0567" | EUPROPID=="COM(1974)0660" | EUPROPID=="COM(1974)1083" | EUPROPID=="COM(1974)1698" | EUPROPID=="COM(1975)0153" | EUPROPID=="COM(1975)0231" | EUPROPID=="COM(1975)0275" | EUPROPID=="COM(1975)0515" | EUPROPID=="COM(1976)0164" | EUPROPID=="COM(1976)0299" | EUPROPID=="COM(1976)0382" | EUPROPID=="COM(1976)0387" | EUPROPID=="COM(1976)0453" | EUPROPID=="COM(1975)0650-01" 
gen duration=adopted-proposed
sum duration if mediumn==1 & proposedpre==1 & legalbase=="11957E043", detail
sum duration if mediumn==1 & proposedpre==0 & legalbase=="11957E043", detail
ttest duration if mediumn==1 & legalbase=="11957E043", by(proposedpre)

*Survival analysis including detection of PH violations

use "C:\Paris replication data_long.dta", clear

*The long version of the replication dataset is already stset as: stset end, id(EUPROPID) failure(event) origin(time start)

*All proposals

stcox i.qmv i.consult i.postparis i.qmvpostparis i.directive, efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis i.directive qmvxlnt consultxlnt directivexlnt , efron nohr

*Directives

stcox i.qmv i.consult i.postparis i.qmvpostparis if type=="pdir", efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis consultxlnt if type=="pdir", efron nohr

*Regulations

stcox i.qmv i.consult i.postparis i.qmvpostparis if type=="preg", efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis consultxlnt if type=="preg", efron nohr

*Decisions

stcox i.qmv i.consult i.postparis i.qmvpostparis if type=="pdec", efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis consultxlnt if type=="pdec", efron nohr

*Interpret model 1 isolate xb for QMVpreparis then QMVpostparis

stcox i.qmv i.consult i.postparis i.qmvpostparis i.directive qmvxlnt consultxlnt directivexlnt , efron nohr
gen myt=_t
predictnl xbpre = _b[1.qmv] + ln(myt)*_b[qmvxlnt], ci(lxbpre uxbpre) var(varxbpre)
gen hrpre = exp(xbpre) 
gen llpre = exp(lxbpre)
gen ulpre = exp(uxbpre)

stcox i.qmv i.consult i.postparis i.qmvpostparis i.directive qmvxlnt consultxlnt directivexlnt , efron nohr
predictnl xbpost = _b[1.qmv] + _b[1.postparis] + _b[1.qmvpostparis] + ln(myt)*_b[qmvxlnt], ci(lxbpost uxbpost) var(varxbpost)
gen hrpost = exp(xbpost) 
gen llpost = exp(lxbpost)
gen ulpost = exp(uxbpost)
sort _t

*Figure 6

twoway line hrpre myt if myt<400, sort color(black) || line llpre myt if myt<400, sort clpattern(dash) clwidth(thin) color(black) || line ulpre myt if myt<400, sort clpattern(dash) clwidth(thin) color(black)  xtitle("Time in Days") ytitle("Hazard Ratio") || line hrpost myt if myt<400, sort color(red) || line llpost myt if myt<400, sort clpattern(dash) clwidth(thin) color(red) || line ulpost myt if myt<400, xlabel(50(50)400) sort clpattern(dash) clwidth(thin) color(red) yline(1)legend(order (1 "Pre-Paris" 4 "Post-Paris") position(6) rows(1)) name(qmvprepostparis, replace)

drop myt xbpre lxbpre uxbpre hrpre llpre ulpre varxbpre xbpost lxbpost uxbpost hrpost llpost ulpost varxbpost

*Interpret model 2 isolate xb for QMVpreparis then QMVpostparis

stcox i.qmv i.consult i.postparis i.qmvpostparis consultxlnt if type=="pdir", efron nohr
predictnl xbpre = _b[1.qmv], ci(lxbpre uxbpre) var(varxbpre)
gen hrpre = exp(xbpre) 
gen llpre = exp(lxbpre)
gen ulpre = exp(uxbpre)

predictnl xbpost = _b[1.qmv] + _b[1.postparis] + _b[1.qmvpostparis], ci(lxbpost uxbpost) var(varxbpost)
gen hrpost = exp(xbpost) 
gen llpost = exp(lxbpost)
gen ulpost = exp(uxbpost)
sort _t
drop xbpre lxbpre uxbpre hrpre llpre ulpre varxbpre xbpost lxbpost uxbpost hrpost llpost ulpost varxbpost

*Interpret model 3 isolate xb for QMVpreparis then QMVpostparis

stcox i.qmv i.consult i.postparis i.qmvpostparis consultxlnt if type=="preg", efron nohr
predictnl xbpre = _b[1.qmv], ci(lxbpre uxbpre) var(varxbpre)
gen hrpre = exp(xbpre) 
gen llpre = exp(lxbpre)
gen ulpre = exp(uxbpre)

predictnl xbpost = _b[1.qmv] + _b[1.postparis] + _b[1.qmvpostparis], ci(lxbpost uxbpost) var(varxbpost)
gen hrpost = exp(xbpost) 
gen llpost = exp(lxbpost)
gen ulpost = exp(uxbpost)
sort _t
drop xbpre lxbpre uxbpre hrpre llpre ulpre varxbpre xbpost lxbpost uxbpost hrpost llpost ulpost varxbpost

*Interpret model 4 isolate xb for QMVpreparis then QMVpostparis

stcox i.qmv i.consult i.postparis i.qmvpostparis consultxlnt if type=="pdec", efron nohr
predictnl xbpre = _b[1.qmv], ci(lxbpre uxbpre) var(varxbpre)
gen hrpre = exp(xbpre) 
gen llpre = exp(lxbpre)
gen ulpre = exp(uxbpre)

predictnl xbpost = _b[1.qmv] + _b[1.postparis] + _b[1.qmvpostparis], ci(lxbpost uxbpost) var(varxbpost)
gen hrpost = exp(xbpost) 
gen llpost = exp(lxbpost)
gen ulpost = exp(uxbpost)
sort _t
drop xbpre lxbpre uxbpre hrpre llpre ulpre varxbpre xbpost lxbpost uxbpost hrpost llpost ulpost varxbpost

*Appendix: models including additional controls for Council preference heterogeneity

stcox i.qmv i.consult i.postparis i.qmvpostparis i.directive councilrangerile councilrangeproeu, efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis i.directive councilrangerile councilrangeproeu qmvxlnt consultxlnt directivexlnt, efron nohr
stcox i.qmv i.consult i.postparis i.qmvpostparis councilrangerile councilrangeproeu if type=="pdir", efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis councilrangerile councilrangeproeu consultxlnt if type=="pdir", efron nohr
stcox i.qmv i.consult i.postparis i.qmvpostparis councilrangerile councilrangeproeu if type=="preg", efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis councilrangerile councilrangeproeu consultxlnt if type=="preg", efron nohr
stcox i.qmv i.consult i.postparis i.qmvpostparis councilrangerile councilrangeproeu if type=="pdec", efron nohr
stphtest, rank detail
stcox i.qmv i.consult i.postparis i.qmvpostparis councilrangerile councilrangeproeu consultxlnt if type=="pdec", efron nohr

